﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Threading;
using BookSourceVerification.utils;
using Newtonsoft.Json;
using NLog;
using NLog.Config;
using NLog.Targets;

namespace BookSourceVerification
{
    /// <summary>
    /// Interaction logic for App.xaml
    /// </summary>
    public partial class App : Application
    {
        public static List<string>? filePaths = new();
        private Mutex _mutex;
        private Logger _logger;

        protected override void OnStartup(StartupEventArgs e)
        {
            _mutex = new Mutex(false, "BookSourceVerification", out var createdNew);
            if (!createdNew)
            {
                MessageBox.Show("已有程序运行", "提示", MessageBoxButton.OK, MessageBoxImage.Error);
                this.Shutdown();
                return;
            }

            // 日志记录
            LoggerConfiguration();
            _logger = LogManager.GetCurrentClassLogger();
            LogManager.ResumeLogging(); // 开启日志接收app错误
            base.OnStartup(e);
            // UI 异常
            this.DispatcherUnhandledException += OnDispatcherUnhandledException;
            // 非UI异常
            AppDomain.CurrentDomain.UnhandledException += CurrentDomainOnUnhandledException;
            // Task 异常
            TaskScheduler.UnobservedTaskException += TaskSchedulerOnUnobservedTaskException;
            // 获取命令行参数
            string[] args = Environment.GetCommandLineArgs();

            for (var i = 0; i < args.Length; i++)
            {
                if (i == 0)
                {
                    continue;
                }

                filePaths.Add(args[i]);
            }

            LogManager.SuspendLogging(); // 暂停日志
        }

        private void TaskSchedulerOnUnobservedTaskException(object? sender, UnobservedTaskExceptionEventArgs e)
        {
            // 处理Task线程内的未处理异常
            _logger.Error("UnobservedTaskException: " + e.Exception);
            // _logger.Error("Task线程异常：" + e.Exception.Message);
            e.SetObserved(); // 设置该异常已察觉，防止程序崩溃
        }

        private void CurrentDomainOnUnhandledException(object sender, UnhandledExceptionEventArgs e)
        {
            // 处理非UI线程上的未处理异常
            Exception? exception = e.ExceptionObject as Exception;
            if (exception != null)
            {
                // 可以在此添加日志记录、用户通知等处理逻辑
                // _logger.Error("发生未处理的异常：" + exception.Message);
                _logger.Error("UnhandledException: " + exception);
            }
        }

        private void OnDispatcherUnhandledException(object sender, DispatcherUnhandledExceptionEventArgs e)
        {
            // 处理UI线程上的未处理异常
            e.Handled = true;
            // 可以在此添加日志记录、用户通知等处理逻辑
            var exception = e.Exception;
            _logger.Error("UI UnhandledException: " + exception);
        }

        private static void LoggerConfiguration()
        {
            var configuration = new LoggingConfiguration();
            var consoleTarget = new ConsoleTarget("console");
            // 创建日志目标，比如控制台输出
            configuration.AddTarget(consoleTarget);
            configuration.AddRule(LogLevel.Error, LogLevel.Fatal, consoleTarget);
            // 创建一个规则，指定日志级别和目标
            var fileTarget = new FileTarget("fileTarget")
            {
                FileName = "error.txt", // 日志文件的名称
                Encoding = Encoding.UTF8, // 文件编码
                KeepFileOpen = false, // 是否保持文件打开状态
                ArchiveAboveSize = 3000000, // 归档文件的最大大小（字节）
                MaxArchiveFiles = 3, // 保留的归档文件数量
                MaxArchiveDays = 7, // 归档文件的最长保留时间（天）
                ConcurrentWrites = false, // 是否允许并发写入
                LineEnding = LineEndingMode.Default // 行结束符模式
            };
            configuration.AddTarget(fileTarget);
            var fileRule = new LoggingRule("*", LogLevel.Error, LogLevel.Fatal, fileTarget);
            configuration.AddRule(fileRule);
            LogManager.Configuration = configuration; // 激活日志配置
            // 暂停日志记录
            LogManager.SuspendLogging();
        }

    }
}